package cn.qpyl.longpoll.netty;

import java.util.HashMap;
import java.util.function.Function;

import io.netty.handler.codec.http.HttpMethod;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class App {

    private String prefx;
    private HashMap<String, App> groupRouter = new HashMap<>();
    private HashMap<String, Function<Request, Object>> getRouter = new HashMap<>();
    private HashMap<String, Function<Request, Object>> postRouter = new HashMap<>();

    private App() {
        prefx = "";
    }

    private App(String pf) {
        prefx = pf;
    }

    public static App Default() {
        return new App();
    }

    public static App New() {
        return new App();
    }

    public App Group(String prexPath) {
        App app = new App(prexPath);
        groupRouter.put(prexPath, app);
        return app;
    }

    public void Get(String path, Function<Request, Object> func) {
        getRouter.put(prefx + path, func);
    }

    public void Post(String path, Function<Request, Object> func) {
        postRouter.put(prefx + path, func);
    }

    private void PaseGroup() {
        if (groupRouter.size() > 0) {
            groupRouter.forEach((k, v) -> {
                v.PaseGroup();
                v.getRouter.forEach((k1, v1) -> {
                    getRouter.put(k1, v1);
                });
                v.postRouter.forEach((k2, v2) -> {
                    postRouter.put(k2, v2);
                });
            });
        }
    }

    public void Dispatcher(Request req) {

        if (req.getReq().method() == HttpMethod.GET) {
            Function<Request, Object> f = getRouter.get(req.getReq().uri());
            if (null != f) {
                f.apply(req);
            } else {
                NotFound(req);
            }
        } else if (req.getReq().method() == HttpMethod.POST) {
            Function<Request, Object> f = postRouter.get(req.getReq().uri());
            if (null != f) {
                f.apply(req);
            } else {
                NotFound(req);
            }
        } else {
            NotFound(req);
        }
    }

    public void NotFound(Request req) {
        req.error(404);
    }

    public void Run(int port) {
        // parse group
        PaseGroup();
        getRouter.forEach((k, v) -> {
            log.info("GET[{}]->{}", k, v.hashCode());
        });
        postRouter.forEach((k, v) -> {
            log.info("POST[{}]->{}", k, v.hashCode());
        });
        new HttpServer(this).start(port);

    }

}